package main

import "fmt"

// 结论:
// (1)map是引用类型， 当把map作为参数传递的时候， 对map进行操作是会改变map的值
// 但是 如果需要操作（修改）map对应的value值， 需要传递对应value的指针
//
// (2)当map的值为一个interface的时候, 取决于你方法集的接受者和传入的值
// 如果方法集的接收者是指针接受者的话， 可以改变对应的值，否则不行
func main() {
	maptest2()
}

func maptest2() {
	jobs := make(map[string]job)
	jobs["001"] = &EchoJob{
		state: "starting",
	}
	opJobs(jobs)

	job := jobs["001"]
	fmt.Println(job.getState())
}

func opJobs(jobs map[string]job) {
	job := jobs["001"]
	job.execute()
	job.changeState("successed")
}

type job interface {
	changeState(string)
	execute()
	getState() string
}

type EchoJob struct {
	state string
}

func (e *EchoJob) changeState(newState string) {
	e.state = newState
}

func (e *EchoJob) execute() {
	fmt.Println("execute job")
}

func (e *EchoJob) getState() string {
	return e.state
}

func maptest1() {
	users := map[string]*user{
		"001": {
			name: "jack",
			age:  21,
		},
	}
	opMap(users)

	printusers(users)
}

func printusers(users map[string]*user) {
	for k, v := range users {
		fmt.Printf("%s: %v\n", k, v)
	}
}

func opMap(users map[string]*user) {
	users["002"] = &user{
		name: "tommy",
		age:  22,
	}
	if v, ok := users["001"]; ok {
		v.name = "jackma"
	}
	printusers(users)
}

type user struct {
	name string
	age  int
}
